package cn.iocoder.yudao.module.hs.service.trayscanrecord;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.hs.controller.admin.trayscanrecord.vo.TrayScanRecordPageReqVO;
import cn.iocoder.yudao.module.hs.controller.admin.trayscanrecord.vo.TrayScanRecordRespVO;
import cn.iocoder.yudao.module.hs.controller.admin.trayscanrecord.vo.TrayScanRecordSaveReqVO;
import cn.iocoder.yudao.module.hs.dal.dataobject.entryorder.EntryOrderDO;
import cn.iocoder.yudao.module.hs.dal.dataobject.picktaskmaterialdetail.PickTaskMaterialDetailDO;
import cn.iocoder.yudao.module.hs.dal.dataobject.receiveorder.ReceiveOrderDO;
import cn.iocoder.yudao.module.hs.dal.dataobject.shiporder.ShipOrderDO;
import cn.iocoder.yudao.module.hs.dal.dataobject.tray.TrayDO;
import cn.iocoder.yudao.module.hs.dal.dataobject.trayscanrecord.TrayScanRecordDO;
import cn.iocoder.yudao.module.hs.dal.mysql.picktaskmaterialdetail.PickTaskMaterialDetailMapper;
import cn.iocoder.yudao.module.hs.dal.mysql.trayscanrecord.TrayScanRecordMapper;
import cn.iocoder.yudao.module.hs.service.entryorder.EntryOrderService;
import cn.iocoder.yudao.module.hs.service.receiveorder.ReceiveOrderService;
import cn.iocoder.yudao.module.hs.service.shiporder.ShipOrderService;
import cn.iocoder.yudao.module.hs.service.tray.TrayService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.hs.enums.ErrorCodeConstants.*;

/**
 * 单号托盘点亮状态记录 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
public class TrayScanRecordServiceImpl implements TrayScanRecordService {

    @Resource
    private TrayScanRecordMapper trayScanRecordMapper;
    @Resource
    private PickTaskMaterialDetailMapper pickTaskMaterialDetailMapper;
    @Resource
    private TrayService trayService;
    @Resource
    private ReceiveOrderService receiveOrderService;
    @Resource
    private EntryOrderService entryOrderService;
    @Resource
    private ShipOrderService shipOrderService;

    @Override
    public Long createTrayScanRecord(TrayScanRecordSaveReqVO createReqVO) {
        Long shipOrderId = null;
        if ("ENTRY".equals(createReqVO.getOrderType())) {
            EntryOrderDO entryOrder = entryOrderService.getEntryOrder(createReqVO.getOrderId());
            if (entryOrder == null) {
                throw exception(ENTRY_ORDER_NOT_EXISTS);
            }
            shipOrderId = entryOrder.getShipOrderId();
        }
        if ("RECEIVE".equals(createReqVO.getOrderType())) {
            ReceiveOrderDO receiveOrder = receiveOrderService.getReceiveOrder(createReqVO.getOrderId());
            if (receiveOrder == null) {
                throw exception(RECEIVE_ORDER_NOT_EXISTS);
            }
            shipOrderId = receiveOrder.getShipOrderId();
        }
        if (shipOrderId != null) {
            ShipOrderDO shipOrder = shipOrderService.getShipOrder(shipOrderId);
            if (shipOrder == null) {
                throw exception(SHIP_ORDER_NOT_EXISTS);
            }
        }
        TrayDO tray = trayService.getTray(createReqVO.getInfoCode());
        if (tray == null) {
            List<PickTaskMaterialDetailDO> pickTaskMaterialDetailDOS = pickTaskMaterialDetailMapper.selectList(PickTaskMaterialDetailDO::getRfidCode, createReqVO.getInfoCode());
            if (CollUtil.isNotEmpty(pickTaskMaterialDetailDOS)) {
                tray = trayService.getTray(pickTaskMaterialDetailDOS.get(0).getTrayCode());
            }
        }
        if (tray == null) {
            throw exception(TRAY_NOT_EXISTS);
        }
        List<PickTaskMaterialDetailDO> pickTaskMaterialDetailDOS = pickTaskMaterialDetailMapper.selectList(PickTaskMaterialDetailDO::getTrayCode, tray.getCode(), PickTaskMaterialDetailDO::getShipOrderId, shipOrderId);
        if (CollUtil.isEmpty(pickTaskMaterialDetailDOS)) {
            throw exception(TRAY_RFID_NOT_IN_ORDER);
        }
        List<TrayScanRecordDO> trayScanRecordDOS = trayScanRecordMapper.selectList(TrayScanRecordDO::getOrderId, createReqVO.getOrderId(), TrayScanRecordDO::getTrayCode, tray.getCode());
        if (CollUtil.isNotEmpty(trayScanRecordDOS)) {
            TrayScanRecordDO trayScanRecordDO = trayScanRecordDOS.get(0);
            if (trayScanRecordDO.getStatus().equals(0)) {
                trayScanRecordDO.setStatus(1);
                trayScanRecordDO.setLightTime(LocalDateTime.now());
                trayScanRecordMapper.updateById(trayScanRecordDO);
                return trayScanRecordDO.getId();
            } else {
                return trayScanRecordDO.getId();
            }
        }
        // 插入
        TrayScanRecordDO trayScanRecord = BeanUtils.toBean(createReqVO, TrayScanRecordDO.class);
        trayScanRecord.setTrayCode(tray.getCode());
        trayScanRecord.setLightTime(LocalDateTime.now());
        trayScanRecord.setStatus(1);
        trayScanRecordMapper.insert(trayScanRecord);
        // 返回
        return trayScanRecord.getId();
    }

    @Override
    public void updateTrayScanRecord(TrayScanRecordSaveReqVO updateReqVO) {
        // 校验存在
        validateTrayScanRecordExists(updateReqVO.getId());
        // 更新
        TrayScanRecordDO updateObj = BeanUtils.toBean(updateReqVO, TrayScanRecordDO.class);
        trayScanRecordMapper.updateById(updateObj);
    }

    @Override
    public void deleteTrayScanRecord(Long id) {
        // 校验存在
        validateTrayScanRecordExists(id);
        // 删除
        trayScanRecordMapper.deleteById(id);
    }

    private void validateTrayScanRecordExists(Long id) {
        if (trayScanRecordMapper.selectById(id) == null) {
            throw exception(TRAY_SCAN_RECORD_NOT_EXISTS);
        }
    }

    @Override
    public TrayScanRecordDO getTrayScanRecord(Long id) {
        return trayScanRecordMapper.selectById(id);
    }

    @Override
    public PageResult<TrayScanRecordDO> getTrayScanRecordPage(TrayScanRecordPageReqVO pageReqVO) {
        return trayScanRecordMapper.selectPage(pageReqVO);
    }

    @Override
    public List<TrayScanRecordRespVO> getTrayScanRecordList(Long orderId, String orderType) {
        if ("ENTRY".equals(orderType)) {
            return trayScanRecordMapper.getEntryOrderTrayList(orderId);
        }
        if ("RECEIVE".equals(orderType)) {
            return trayScanRecordMapper.getReceiveOrderTrayList(orderId);
        }
        return null;
    }
}